<!--
@description    封装通用表格入口组件
@author         秦俊强
@email          458112865@qq.com
@create         2020-02-01 17:30
-->

<template>
  <div class="ant-card ant-card-body">

    <!-- 公共菜单区 start -->
    <div class="menu-box">
      <a-row :gutter="10">
        <a-col :md="13" :sm="24">
          <div class="query-date">
            <span>考核期：</span>
            <a-select v-if="!yearMonthList.loading"
                      :value="yearMonthList.val.text" @change="changeDate" style="width: 150px">
              <a-select-option v-for="date in yearMonthList.arr"
                               :key="date.value">{{ date.text }}</a-select-option>
            </a-select>
            <a-select v-else :defaultValue="'数据加载中'" disabled></a-select>
          </div>

          <div class="query-depart">
            <span>组织类型：</span>
            <a-select v-if="!departInfo.loading"
                      :value="departInfo.arr[departInfo.index].name"
                      @change="departChange">
              <a-select-option v-for="depart in departInfo.arr"
                               :key="depart.code">{{ depart.name }}</a-select-option>
            </a-select>
            <a-select v-else :defaultValue="'数据加载中'" disabled></a-select>
          </div>

          <div class="query-target" v-if="showMenu('target')">
            <span>考核指标：</span>
            <a-select mode="multiple" placeholder="全部指标"
                      :allowClear="true" :maxTagCount="0"
                      :dropdownMatchSelectWidth="false"
                      :showArrow="true"
                      :value="targetInfo.indexs"
                      @change="targetChange">
              <a-select-option v-for="target in targetInfo.arr"
                               :key="target.code"
                               :title="target.name">{{ target.name }}</a-select-option>
            </a-select>
          </div>

          <!-- 绩效计算审核 -->
          <div class="query-target" v-if="k === 'mgr'">
            <span>维度：</span>
            <a-select mode="multiple" placeholder="全部维度"
                      :allowClear="true" :maxTagCount="0"
                      :dropdownMatchSelectWidth="false"
                      :showArrow="true"
                      :value="dimensionInfo.indexs"
                      @change="dimensionChange">
              <a-select-option v-for="dim in dimensionInfo.arr"
                               :key="dim.code"
                               :title="dim.name">{{ dim.name }}</a-select-option>
            </a-select>
          </div>
        </a-col>

        <a-col :md="11" :sm="24" v-if="showMenu('btn')">
          <div class="btn-box" v-if="!isEditAll">

            <a-button :type="'primary'" icon="sound" v-if="k === 'mgr'"
                      :disabled="isDisabled('verify')"
                      @click="auditAction()">提交审核</a-button>

            <a-button v-if="!isEditRow" :type="'primary'" icon="edit"
                      :disabled="isDisabled()"
                      @click="switchEditTab(true)">批量编辑</a-button>

            <a-button v-else :type="'primary'" :disabled="true" icon="edit"
                      title="当前有正在编辑的内容">批量编辑</a-button>

            <!--<a-button :type="'primary'" icon="save"
                      :disabled="isDisabled()"
                      @click="submitData('save')">保存数据</a-button>-->

            <!-- 只有 绩效计算审核 模块才显示 -->
            <a-button :type="'primary'" icon="sliders" v-if="k === 'mgr'"
                      :disabled="isDisabled()"
                      @click="submitData('calcScores')">得分计算</a-button>
          </div>

          <div class="btn-box" v-else>
            <a-button :type="'primary'" icon="check" :disabled="isDisabled()"
                      @click="submitData('save')">全部保存</a-button>
            <a-button icon="close" :disabled="isDisabled()"
                      @click="switchEditTab()">全部取消</a-button>
          </div>
        </a-col>
      </a-row>
    </div>
    <!-- 公共菜单区 end -->



    <!-- 状态栏 绩效汇总计算展示 start -->
    <div class="status-box" v-if="k === 'mgr'">
      <div class="item-box">
        <span class="title">当前审核状态：</span>
        <span class="val" v-if="!status.loading"
              :class="'status-' + status.val.key">{{ status.val.value }}</span>
        <span v-else>loading...</span>
      </div>

      <div class="item-box" v-if="taskStatus != '0'">
        <span><a-icon type="exclamation-circle" /> </span>
        <span> 注意：当前绩效计算任务正在进行中，不能进行提交和编辑计算。</span>
      </div>
    </div>
    <!-- 状态栏 绩效汇总计算展示 start -->



    <!-- 表格数据 start -->
    <div class="table-box">
      <KpiTableCommon v-if="!departInfo.loading"
                      :ref="k" :k="k" :isEditAll="isEditAll"
                      :date="yearMonthList.val.value"
                      :targets="targetInfo.indexs"
                      :dimensions="dimensionInfo.indexs"
                      :headerInfo="departInfo"
                      :status="status.val.key"></KpiTableCommon>
    </div>
    <!-- 表格数据 end -->

  </div>
</template>



<script>
  /* 引入 api 接口配置 */
  import { apiConfig } from './api.config.js';

  /* 引入通用表格组件 */
  import KpiTableCommon from './table.common';





  export default {
    name: 'kpi-table-common',
    components: { KpiTableCommon },

    props: {
      /**
       * @description       标识是哪个模块页面的表头（必传项）
       * @example           <kpiTableCommon :k="fill"></kpiTableCommon>
       *
       * k = 'fill'         绩效管理-绩效填报
       * k = 'target'       绩效管理-设定绩效目标值
       * k = 'audit'        绩效审核-绩效审核记录（只有查询，并且表头是固定的）
       * k = 'weight'       绩效维护-权重管理
       * k = 'mgr'          绩效管理-绩效汇总计算（现在叫 绩效计算审核）
       * */
      k: {
        type: String,
        default: ''
      }
    },

    data() {
      return {

        /* 年月下拉菜单 */
        yearMonthList: {
          loading: true,
          arr: [],    // 可选择的年月列表
          val: {}     // 已选年月，默认数组第 0 个
        },

        /* 部门下拉选项菜单 */
        departInfo: { loading: true, arr: [], index: 0 },

        /* 指标下拉选项菜单 */
        targetInfo: { arr: [], indexs: [] },

        /* 维度 */
        dimensionInfo: { arr: [], indexs: [] },

        /* 审核状态 (1:待申请；2:审核中（待审核）; 3:已审核; 4:已退回)  */
        status: { loading: true, val: {} },

        /* 任务状态 0 任务完成 | 1 任务进行中 | 2 任务异常 */
        taskStatus: '0',

        /* 是否为编辑状态 */
        isEditAll: false,

        /* 是否在编辑单行 */
        isEditRow: false,

        /* 是否保存中 */
        isSavingAll: false,

        /* 数据是否有修改 */
        isEditChange: false,

        /* 是否无数据 */
        isNotData: true,

        /* 用于延时调用搜索接口 */
        timeout: null
      };
    },

    created() {
      /* 获取评分年月 */
      this.yearMonthList.loading = true;

      // 针对 绩效数据填报和绩效计算审核 模块做处理
      let fn = null;
      if('fill' == this.k){
        fn = 'currentYearMonthList';
      }else if('mgr' == this.k){
        fn = 'getKpiYearMonthList';
      }else{
        fn = 'getYearMonthList';
      }

      apiConfig['common'][fn]().then((res) => {
        let list = res.result || [];
        this.yearMonthList = {
          loading: false,
          arr: list || [],
          val: list[0] || {}
        };

        this.getConditions();     // 获取部门下拉选项菜单
      }).catch((error) => {
        this.yearMonthList.loading = false;
        this.$message.error(error.message);
      });

      // 并发调用
      // let target = apiService(getIndexCodes());
      /*Promise.all([depart, target]).then((ress) => {
        // console.log('ress = ', ress);

        this.departInfo.arr = ress[0].result || [];
        this.targetInfo.arr = ress[1].result || [];
      }).catch((error) => {
        this.$message.error(error.message);
      });*/
    },

    methods: {

      /**
       * 按钮禁用
       * */
      isDisabled(str) {
        let t = this;
        let key = t.status.val.key;

        /* 0. 如果当前无数据 */
        if (t.isNotData) { return true; }

        // 1. 如果是保存中，禁用按钮
        if (t.isSavingAll) { return true; }

        // 2. 如果当前有一行正在编辑，禁用按钮
        if (t.isEditRow) { return true; }

        // 3. 当前页面为绩效汇总计算
        if (t.k === 'mgr') {

          // 任务状态为 0 时，才能点击 提交审核 按钮
          if (str === 'verify') {
            return !(t.taskStatus == '0') || (['0', '1', '4'].indexOf(key) < 0);
          }

          // 当前审核状态不为 0 已初审 | 1 待申请 | 4 已退回时，禁用按钮
          if (['0', '1', '4'].indexOf(key) < 0) { return true; }
        }

        return false;
      },

      /* 监听组织切换 */
      departChange(code) {
        let arr = this.departInfo.arr;
        this.departInfo.index = arr.findIndex((item) => { return item.code === code });
        this.switchEditTab();
        this.getIndexCodes();
        this.update();
      },

      /**
       * 监听考核指标变化
       *
       * 【逻辑】首先清除定时器，再开启定时器延时调用接口
       * 【原因】因为选择考核指标是多选，不能频繁调用接口，减少重复请求
       * */
      targetChange(codes) {
        // 清除定时器
        clearTimeout(this.timeout);

        this.targetInfo.indexs = codes;
        let num = (codes.length === 0) ? 300 : 1300;  // 如果是清空操作，延时短一点；如果是多选，时间长一点；
        this.timeout = setTimeout(() => { this.update(); }, num);
      },

      /**
       * 监听维度变化
       *
       * 【逻辑】首先清除定时器，再开启定时器延时调用接口
       * 【原因】因为选择考核指标是多选，不能频繁调用接口，减少重复请求
       * */
      dimensionChange(codes) {
        // 清除定时器
        clearTimeout(this.timeout);

        this.dimensionInfo.indexs = codes;
        let num = (codes.length === 0) ? 300 : 1300;  // 如果是清空操作，延时短一点；如果是多选，时间长一点；
        this.timeout = setTimeout(() => { this.update(); }, num);
      },

      /* 监听考核期变化 */
      changeDate(code) {
        let arr = this.yearMonthList.arr;
        this.yearMonthList.val = arr.find((item) => { return (item.value === code); });
        this.switchEditTab();
        this.getConditions();
        this.update();
      },

      /* 通知子组件更新数据 */
      update() {
        setTimeout(() => {
          let fn = 'update';
          if (this.k === 'audit') { fn = 'getAuditData'; }
          if (this.k === 'mgr') { this.status.loading = true; }

          // 通知子组件【更新】数据，子组件必须要有 update 这个方法
          this.$refs[this.k] && this.$refs[this.k][fn](true);
        }, 10);
      },

      /* 全部保存 */
      submitData(fnStr) {
        this.isSavingAll = true;

        setTimeout(() => {
          // 通知子组件保存当前列表的全部数据，子组件必须要有 save 这个方法
          this.$refs[this.k] && this.$refs[this.k].submitData(fnStr);
        }, 10);
      },

      /* 切换编辑状态 */
      switchEditTab(b) {
        this.isEditAll = b || false;
        this.isSavingAll = false;
      },

      /* 是否需要显示菜单项 */
      showMenu(str) {
        // 绩效审核记录页面【隐藏】考核指标 target 下拉菜单 和 按钮 btn
        if (this.k === 'audit') {
          return !(['target', 'btn'].indexOf(str) >= 0);
        }

        return true;
      },

      /* 获取部门下拉选项菜单 */
      getConditions() {
        this.departInfo.loading = true;
        let param = {
            indexYearMonth  : this.yearMonthList.val.value
        }
        apiConfig[this.k].getMenu(param).then((res) => {
          this.departInfo.loading = false;

          /**
           * 下拉菜单赋值
           * audit 绩效审核记录模块 可以选择 全部
           * */
          if (this.k === 'audit') {
            this.departInfo.arr = res.result.orgTypes;
            this.departInfo.arr.unshift({ code: "", name: "全部" });
          } else {
            this.departInfo.arr = res.result;
          }

          // 取指标下拉菜单，因为存在级联的依赖关系
          this.getIndexCodes();

          // 获取维度下拉菜单
          this.getIndexAttrs();

          // 如果是 绩效汇总计算，需要获取审核状态信息
          if (this.k === 'mgr') {
            this.getStatus();       // 审核状态
            this.getTaskStatus();   // 任务状态
          }
        }).catch((error) => {
          this.departInfo.loading = false;
          this.$message.error(error.message);
        });
      },

      /* 获取指标下拉选项菜单 */
      getIndexCodes() {
        let departInfo = this.departInfo;
        let param = { indexGroup: departInfo.arr[departInfo.index].code }

        this.targetInfo = { arr: [], indexs: [] };
        apiConfig['common'].getIndexCodes(param).then((res) => {
          this.targetInfo.arr = res.result || [];
        }).catch((error) => {
          this.$message.error(error.message);
        });
      },

      /* 获取维度下拉选项菜单 */
      getIndexAttrs() {
        this.dimensionInfo = { arr: [], indexs: [] };
        apiConfig['common'].getIndexAttrs().then((res) => {
          this.dimensionInfo.arr = res.result || [];
        }).catch((error) => {
          this.$message.error(error.message);
        });
      },

      /* 获取审核状态，针对绩效汇总计算模块 */
      getStatus() {
        let param = {
          indexYearMonth: this.yearMonthList.val.value,
          indexGroup: this.departInfo.arr[this.departInfo.index].code
        }
        this.status.loading = true;
        apiConfig[this.k].getStatus(param).then((res) => {
          this.status.loading = false;
          let result = res.result;

          if (!result.indexAuditStatus) {
            this.status.val = { value: '状态异常，您可以尝试刷新或联系相关人员', key: '' };
            return;
          }

          this.status.val = result.indexAuditStatus;
        }).catch((error) => {
          this.status.loading = false;
          this.$message.error(error.message);
        });
      },

      /* 提交审核 目前只针对绩效汇总计算 */
      auditAction() {
        let t = this;
        let content = '注意：提交后，将不能进行编辑、保存和计算等操作！';

        t.$confirm({
          title: '确定要提交审核吗？',
          content: content,
          width: '450px',
          okText: '提交审核',
          cancelText: '取消',
          okType: 'danger',
          icon: 'exclamation-circle',
          onOk() {
            let param = {
              indexYearMonth: t.yearMonthList.val.value,
              indexGroup: t.departInfo.arr[t.departInfo.index].code,
              auditType: 'atSubmit',      // 标记提交审核
              auditComments: ''
            }

            apiConfig[t.k].auditAction(param).then(() => {
              t.$message.success('提交成功');
              t.getStatus();
            }).catch((error) => {
              t.$message.error(error.message);
            });
          }
        });
      },

      /* 定时获取任务 */
      getTaskStatus() {
        let time = 20 * 1000;
        let param = {
          taskCode        : 'tcAuditCalc',    // 标记任务的唯一标识
          indexYearMonth  : this.yearMonthList.val.value,
          indexGroup      : this.departInfo.arr[this.departInfo.index].code
        }

        apiConfig.common.getTaskStatus(param).then((res) => {
          let result = res.result;
          this.taskStatus = result.tcResult;

          // 0 任务完成 | 1 任务进行中 | 2 任务异常
          if (result.tcResult == '0') { return; }
          setTimeout(() => { this.getTaskStatus(); }, time);
        }).catch(() => {
          setTimeout(() => { this.getTaskStatus(); }, time);
        });
      }

    },
  };
</script>



<style lang="less" scoped>
  .menu-box {
    margin-bottom: 10px;

    [class*="query-"] {
      float: left;
      margin-right: 10px;
    }

    .query-depart {
      /deep/.ant-select {
        width: 120px;
      }
    }

    .query-date {
      /deep/.ant-calendar-picker-input {
        width: 100px;
      }
    }

    .query-target {
      /deep/.ant-select {
        width: 120px;
      }
    }

    .btn-box {
      float: right;
      button { margin-left: 4px; }
    }
  }

  .status-box {
    font-size: 12px;

    .item-box {
      float: left;
      margin: 0 10px 10px 1px;
      padding: 2px 10px;
      border-radius: 2px;
      border: 1px solid #e7e7e7;
      background-color: #fafafa;
      color: #F1523A;
      font-weight: bold;
    }

    .val { font-weight: bold; }
    .title { color: #666666; }

    /* 审批状态(0: 已初审; 1:待申请; 2:审核中; 3:已审核; 4:已退回) */
    .status-0 { color: #808080; }   /* 灰色 */
    .status-1 { color: #14BA89; }   /* 绿色 */
    .status-2 { color: #FF6600; }   /* 橙色 */
    .status-3 { color: #5FBBFC; }   /* 蓝色 */
    .status-4 { color: #F1523A; }   /* 红色 */
  }
</style>


